import threading
class ClientRun(threading.Thread):
    def run(self):
        import socket
        self.setDaemon(True)

        serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #serversocket.connect(("169.254.7.215", 3340))
        serversocket.connect(("192.168.1.102", 3340))
        agent = BIFTClientAgent()
        while 1:

            incomingCommand = raw_input()
            if incomingCommand == 'quit!':
                serversocket.close()
                break
            serversocket.send(agent.sendData(incomingCommand))
            while 1:
                data = serversocket.recv(1024) # receive up to 1K bytes
                agent.receiveData(data)
                if agent.ResultType == 'binary':
                    x = 0
                    #while x < agent.FileSize/1024 and data:
                    data1 = data
                    while data.rfind('___!___endoffile') <  0:
                    #while len(data1) < agent.FileSize:
                        data = serversocket.recv(agent.FileSize - len(data1))
                        #data = serversocket.recv(1024)
                        agent.fileAssemble(data)
                        x = x + 1

                    #agent.receiveData(data1)
                    file = open(agent.FileName, "wb")
                    agent.currentFile = agent.currentFile.replace("___!___endoffile", "")
                    file.writelines(eval(agent.currentFile))
                    file.close()
                    agent.currentFile = ''

                incomingCommand = raw_input()
                if incomingCommand == 'quit!':
                    serversocket.close()
                    break
                serversocket.send(agent.sendData(incomingCommand))
                



class BIFTProtocol:
    ResultType = ''
    payload = None
    FileSize = 0
    FileName = ''
    
    def receiveData(self, obj):
        header = obj[0:obj.rfind('|||')]
        self.payload = obj.replace(obj[0:obj.rfind('|||')], "")
        self.payload = self.payload.replace("___!___endoffile", "")
        self.payload = self.payload.replace("|||", "")
        self.analyseHeader(header)

    def analyseHeader(self, header):
        headerContents = header.split('|||')
        self.ResultType = headerContents[1]
        self.FileName = headerContents[3]
        self.FileSize = int(headerContents[0])

    def assemblePacket(self, payload, packetType, filePart, fileName):
        import os
        if packetType == 'command' or packetType == 'list':
            size = len(str(payload))
        else:
            size =  os.path.getsize(fileName)

        return str(size) + "|||" + str(packetType) + "|||" + "1" + "|||" + str(fileName) + "|||" + str(payload) + "___!___endoffile"

class BIFTServerAgent(BIFTProtocol):
    currentFile = None
    
    def receiveData(self, obj):
        BIFTProtocol.receiveData(self, obj)
        result = None
        if self.ResultType == 'command':
            result = self.sintaxAnalyse(self.payload)
        elif self.ResultType == 'binary':
            result = self.fileAssemble(self.payload)
        else:
            result = self.returnData(self.payload)

        return BIFTProtocol.assemblePacket(self, result[0], result[1], result[2], result[3]);

    def sintaxAnalyse(self, payload):
        payloadResult = None
        fileName = ''
        if payload == "list":
            payloadResult = FileManager().listFiles()
            self.ResultType = 'list'
        elif payload.rfind('cd ') >= 0:
            payloadResult = FileManager().cd(payload.replace("cd ", ""))
            self.ResultType = 'command'
        elif payload.rfind('get ') >= 0:
            payloadResult = FileManager().getFile(payload.replace("get ", ""))
            fileName = payload.replace("get ", "")
            self.ResultType = 'binary'
        else:
            payloadResult = "Not a command"

        result = [payloadResult, self.ResultType, "", fileName] 
        return result;

    def fileAssemble(self, payload):
        print("Not implemented")

    def returnData(self, payload):
        print("Not implemented")



class FileManager:
    def listFiles(self):
        import os
        return os.listdir(os.getcwd())

    def cd(self, newDir):
        import os
        os.chdir(newDir)

    def getFile(filePath):
        file = open(filePath, "rb")
        return file.readlines()


class BIFTClientAgent(BIFTProtocol):
    currentFile = None

    def getCurrentFile(self):
        return self.currentFile
    
    def receiveData(self, obj):
        currentFile = ''
        BIFTProtocol.receiveData(self, obj)
        if self.ResultType == 'list':
            print(self.payload)
        elif self.ResultType == 'binary':
            
            self.fileAssemble(self.payload)
        else:
            print("Not valid or not implemented yet.")

    def sintaxAnalyse(self, payload):
        print("Not implemented")

    def sendData(self, object):
        return BIFTProtocol.assemblePacket(self, object, 'command', '1', 'none')

    def fileAssemble(self, payload):
        if self.currentFile == None:
            self.currentFile = ''
        self.currentFile+= payload

    def returnData(self, payload):
        print("Not implemented")
    


        
